		TITLE	LINNUM - Copyright (c) SLR Systems 1994

		INCLUDE MACROS
		INCLUDE	SYMBOLS
		INCLUDE	MODULES
		INCLUDE	IO_STRUC

		PUBLIC	LINNUM,LINNUM32,LINNUM_CONTINUE


		.DATA

		EXTERNDEF	DEBUG_TYPES_SELECTED:BYTE,SYMBOL_TEXT:BYTE

		EXTERNDEF	END_OF_RECORD:DWORD,LINNUM_ADDER:DWORD,LINNUM_DELTA:DWORD,DEFAULT_SIZE:DWORD,LIN_SIZE:DWORD
		EXTERNDEF	LIN_SRC_GINDEX:DWORD,LIN_GROUP_GINDEX:DWORD,LIN_SEGMOD_GINDEX:DWORD,LIN_CSEG_GINDEX:DWORD
		EXTERNDEF	LIN_LAST_LINNUM:DWORD,THEADR_TEMP:DWORD,SYMBOL_LENGTH:DWORD

		EXTERNDEF	GROUP_LARRAY:LARRAY_STRUCT,SEGMOD_LARRAY:LARRAY_STRUCT,SYMBOL_LARRAY:LARRAY_STRUCT
		EXTERNDEF	SYMBOL_GARRAY:STD_PTR_S


		.CODE	PASS1_TEXT

		externdef	_linnum_alloc:proc
		EXTERNDEF	LINNUM_ALLOC:PROC,INDEX_RANGE:PROC,OBJ_PHASE:PROC,FIX_LIN_CSEG:PROC,GET_THEADR:PROC
		EXTERNDEF	DEFINE_SEGMOD_0:PROC,LINSYM_CONT:PROC,SRCNAME_INSTALL:PROC,OPTI_MOVE_PRESERVE_IGNORE:PROC


LINNUM32	PROC

		MOV	EAX,MASK BIT_32
		JMP	LINNUM_COMMON

		DOLONG	L1
		DOLONG	L2

LINNUM_M_VIRDEF:
		;
		;PROBABLY A VIRDEF REFERENCE...
		;
		CONVERT_MYCOMDAT_EAX_ECX
		JC	LINNUM_N_VIRDEF
		JMP	LINSYM_CONT

LINNUM_RET:
		RET

LINNUM::
if	fg_phar
		MOV	EAX,DEFAULT_SIZE
else
		XOR	EAX,EAX
endif

LINNUM_COMMON:
		GETT	BL,KEEPING_LINNUMS
		GETT	CL,DEBUG_TYPES_SELECTED

		OR	BL,BL
		JZ	LINNUM_RET		;SKIP IF WE ARE NOT KEEPING LINE-NUMBERS

		AND	CL,MASK FL_DEBUG_LINNUMS
		JZ	LINNUM_RET		;SKIP IF NOT DEBUGGING THIS MODULE

		MOV	LIN_SIZE,EAX
		NEXT_INDEX	L1		;GET GROUP LINDEX
;		MOV	LIN_GROUP_GINDEX,EAX
		NEXT_INDEX	L2		;GET SEGMOD LINDEX
		MOV	EDI,END_OF_RECORD
		MOV	EDX,EAX
		MOV	LIN_SEGMOD_GINDEX,EAX
		SUB	EDI,ESI
;		MOV	EAX,LIN_GROUP_GINDEX
		JBE	LINNUM_RET		;SKIP IF ZERO ENTRIES IN RECORD

;		TEST	EAX,EAX
;		JZ	L1$
;		CONVERT_LINDEX_EAX_EAX	GROUP_LARRAY,EBX
;		MOV	LIN_GROUP_GINDEX,EAX	;SAVE GROUP FOR GET_THEADR
;L1$:
		MOV	EAX,EDX
		;CMP	EDX,16K			;FOR BORLAND, MIGHT BE VIRDEF REFERENCE
		;JA	LINNUM_M_VIRDEF
LINNUM_N_VIRDEF:
		CONVERT_LINDEX_EAX_EAX		SEGMOD_LARRAY,EBX
LINNUM_Y_VIRDEF:
		MOV	LIN_SEGMOD_GINDEX,EAX	;SAVE SEGMOD FOR GET_THEADR

		;need to allocate room for this record and a couple ptrs

LINNUM_CONT	LABEL	PROC
		;
		;SEE IF LINNUM_DELTA FROM INCREMENTAL COMPILE...
		;
		MOV	EDX,LINNUM_DELTA
		MOV	EBX,LIN_SRC_GINDEX

		TEST	EDX,EDX
		JNZ	L4$
L4$_RET:
		TEST	EBX,EBX
		JZ	L5$
L1$:
		LEA	EAX,[EDI + SIZE LINNUM_HEADER_TYPE]
SPEC_RET:
		sub	ESP,12
		mov	EDX,ESP
		push	EDX		; &EAX
		add	EDX,4
		push	EDX		; &ECX
		add	EDX,4
		push	EDX		; &EDX
		push	EAX
		call	_linnum_alloc
		add	ESP,16
		test	EAX,EAX
		pop	EAX
		pop	ECX
		pop	EDX

;		CALL	LINNUM_ALLOC	;EAX=BLK BASE, ECX PHYS

		PUSH	EBP

;		JC	SPECIAL
		jnz	SPECIAL

		MOV	EDX,EDI		;# OF BYTES IN FIRST BLOCK...
SPEC_2:
		ASSUME	ECX:PTR LINNUM_HEADER_TYPE

		MOV	EBP,LINNUM_ADDER

		MOV	[ECX]._LN_BLOCK_BASE,EAX
		ADD	DPTR [EAX],EBP

		XOR	EAX,EAX
		MOV	LIN_LAST_LINNUM,ECX

;_LN_BLOCK_BASE		DD	?
;_LN_NEXT_LINNUM	DD	?	;NEXT LINNUM RECORD THIS SEG_SRC_MOD
;_LN_LENGTH		DW	?	;OVERALL BYTES IN RECORD
;_LN_TYPE		DB	?	;16 OR 32 BIT, BIT FOR USE-GROUP
;			DB	?
;_LN_SRC_GINDEX		DD	?	;SRC FILE # THIS MODULE

		MOV	[ECX]._LN_NEXT_LINNUM,EAX
		MOV	EAX,LIN_SIZE

		SHL	EAX,16
		MOV	EBP,LIN_SRC_GINDEX	;PROPER SOURCE FILE

		OR	EAX,EDI
		MOV	[ECX]._LN_SRC_GINDEX,EBP

		MOV	DPTR [ECX]._LN_LENGTH,EAX
		MOV	EAX,EBX			;SECOND BLOCK PTR

		MOV	EBX,EDI			;# OF BYTES
		LEA	EDI,[ECX+ SIZEOF LINNUM_HEADER_TYPE]	;DESTINATION

		MOV	ECX,EDX			;# IN FIRST BLOCK
		MOV	EDX,EAX			;SECOND BLOCK

		;
		;EBX IS # OF BYTES
		;ECX IS # IN FIRST BLOCK
		;EDX IS SECOND BLOCK
		;ESI IS SOURCE DATA
		;EDI IS DESTINATION
		;
		SUB	EBX,ECX		;EBX IS # IN SECOND BLOCK
		;
		;NOW MOVE REST OF FIRST BLOCK
		;
		OPTI_MOVSB
		;
		MOV	ECX,EBX
		TEST	EBX,EBX

		MOV	EDI,EDX
		JZ	LE_DONE

		MOV	EAX,LINNUM_ADDER
		ADD	DPTR [EDX-BLOCK_BASE],EAX
		;
		;
		;NOW MOVE REST OF RECORD
		;
		OPTI_MOVSB
		JMP	LE_DONE

L4$:
		MOV	EAX,ESI
		MOV	ECX,EDI
		CALL	PROCESS_LINNUM_DELTA
		JMP	L4$_RET

L5$:
		CALL	GET_THEADR		;DEFINES SRC_INDEX
		JMP	L1$

SPECIAL:
		SUB	EDX,SIZE LINNUM_HEADER_TYPE	;I WANT HEADER MINIMUM
		JC	SPEC1
		;
		;HARD ONE, SET UP STUFF FOR DOING IT CORRECTLY...
		;
		PUSHM	EAX,ECX,EDX
		OR	LIN_SIZE,MASK BIT_CONT

		MOV	EAX,EDI
		MOV	LIN_LAST_LINNUM,ECX
		SUB	EAX,EDX		;NEED THIS MANY MORE

		sub	ESP,12
		mov	EDX,ESP
		push	EDX
		add	EDX,4
		push	EDX
		add	EDX,4
		push	EDX
		push	EAX
		call	_linnum_alloc
		add	ESP,16
		pop	EAX
		pop	ECX
		pop	EDX
		;CALL	LINNUM_ALLOC	;GET MORE...

		POP	EDX
		MOV	EBX,ECX
		POPM	ECX,EAX
		JMP	SPEC_2

SPEC1:
		;
		;CANT EVEN FIT HEADER, RELEASE THIS
		;
		POP	EBP
		DEC	DPTR [EAX]	;DON'T COUNT THAT GUY

		LEA	EAX,[EDI+SIZE LINNUM_HEADER_TYPE]
		JMP	SPEC_RET

LE_DONE:
		POP	EBP
		CALL	FIX_LIN_CSEG		;RETURNS DS:SI POINTING
		ASSUME	EAX:PTR CSEG_STRUCT

		MOV	EBX,LIN_LAST_LINNUM
		MOV	ECX,[EAX]._CSEG_LAST_LINNUM
		ASSUME	ECX:PTR LINNUM_HEADER_TYPE

		MOV	[EAX]._CSEG_LAST_LINNUM,EBX
		TEST	ECX,ECX

		JZ	L8$

		MOV	[ECX]._LN_NEXT_LINNUM,EBX
		RET

L8$:
		MOV	[EAX]._CSEG_FIRST_LINNUM,EBX
		RET

LINNUM32	ENDP


LINNUM_CONTINUE	PROC

		MOV	EDI,ECX
		MOV	ESI,EAX

		JMP	LINNUM_CONT

LINNUM_CONTINUE	ENDP


GET_THEADR	PROC
		;
		;MAKE SURE THEADR ADDRESS IS VALID,  LIN_SRC_INDEX
		;
		PUSHM	EDI,ESI

		MOV	ESI,OFF THEADR_TEMP+4
		MOV	EAX,DPTR THEADR_TEMP

		MOV	EDI,OFF SYMBOL_TEXT
		MOV	SYMBOL_LENGTH,EAX

		CALL	OPTI_MOVE_PRESERVE_IGNORE	;HASH IN EDX

		POP	ESI
		CALL	SRCNAME_INSTALL		;RETURN EAX IS GINDEX, ECX IS ADDRESS

		POP	EDI
		MOV	LIN_SRC_GINDEX,EAX
		RET

GET_THEADR	ENDP


PROCESS_LINNUM_DELTA	PROC
		;
		;EAX IS RECORD, ECX IS LENGTH
		;
		PUSHM	EDI,ESI,EBX
		MOV	EBX,EDX

		XOR	EDX,EDX
		MOV	ESI,EAX

		MOV	EAX,ECX
		MOV	ECX,4

		CMP	LIN_SIZE,EDX
		JZ	L2$

		INC	ECX

		INC	ECX
L2$:
		DIV	CX

		MOV	EDI,ECX

		NEG	EDI
L3$:
		MOV	EDX,[ESI]
		ADD	ESI,ECX

		AND	EDX,0FFFFH
		JZ	L4$

		ADD	EDX,EBX
L4$:
		DEC	EAX

		MOV	[ESI+EDI],DX
		JNZ	L3$

		POPM	EBX,ESI,EDI
		RET

PROCESS_LINNUM_DELTA	ENDP


		END

